package com.lz.sports.db

import android.text.TextUtils
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.lz.library.extension.APP
import com.lz.sports.bean.DeviceGroup
import com.lz.sports.bean.DeviceInfo

@Database(
    entities = [DeviceGroup::class, DeviceInfo::class],
    version = 1
)
//由于设备的频繁使用,使用全局单例
abstract class DeviceDatabase : RoomDatabase() {

    companion object {

        private const val DB_NAME = "Device.db"

        private var INSTANCE: DeviceDatabase? = null

        fun get(): DeviceDatabase {
            if (INSTANCE == null) {
                synchronized(DeviceDatabase::class.java) {
                    if (INSTANCE == null) INSTANCE = Room.databaseBuilder(APP, DeviceDatabase::class.java, DB_NAME)
                        .allowMainThreadQueries().build()
                }
            }
            return INSTANCE!!
        }
    }

    abstract fun getDeviceGroupDao(): DeviceGroupDao

    abstract fun getDeviceInfoDao(): DeviceInfoDao

    /* -----------------------    DeviceGroup相关的搜索     --------------------- */

    //添加组
    fun addDeviceGroup(deviceGroup: DeviceGroup): Int = getDeviceGroupDao().insert(deviceGroup).toInt()

    //查询所有分组
    fun findDeviceGroupListWithInfo(projectId: Int): List<DeviceGroup> {
        val deviceGroupList = getDeviceGroupDao().deviceGroupListWithInfo(projectId)
        val groupList = ArrayList<DeviceGroup>(deviceGroupList.size)
        for (deviceGroupWithInfo in deviceGroupList) {
            if (deviceGroupWithInfo.isInvalid()) continue
            deviceGroupWithInfo.group!!.initDeviceInfoList(deviceGroupWithInfo.deviceInfoList!!)
            groupList.add(deviceGroupWithInfo.group!!)
        }
        return groupList
    }

    //查询所有分组, 不带分组设备信息
    fun findDeviceGroupList(projectId: Int): List<DeviceGroup> = getDeviceGroupDao().deviceGroupList(projectId)

    //删除组
    fun deleteDeviceGroup(groupId: Int) {
        getDeviceInfoDao().deleteGroup(groupId)
        getDeviceGroupDao().deleteGroup(groupId)
    }

    //找出辅助设备列表
    fun findAssistDeviceInfoList(projectId: Int): List<DeviceInfo> = getDeviceInfoDao().findAssistDeviceInfoList(projectId)

    //修改设备名
    fun modifyDeviceGroupName(newName: String, groupId: Int) {
        getDeviceGroupDao().modifyGroupName(newName, groupId)
    }

    //全部解绑
    fun unbindGroup(groupId: Int) {
        getDeviceInfoDao().unbindDeviceGroup(groupId)
        getDeviceGroupDao().unbindGroup(groupId)
    }

    //修改序号
    fun modifyDeviceInfoNumber(group: DeviceGroup, deviceInfo: DeviceInfo) {
        getDeviceInfoDao().modifyNumber(deviceInfo.number, deviceInfo.id)
        getDeviceGroupDao().updateGroup(group)
    }










    //查询所有分组
    fun findDeviceGroupListWithInfo(): List<DeviceGroup> {
       /* val groupList = getDeviceGroupDao().findDeviceGroupList()
        for (group in groupList) {
            //后期考虑 组合直接查询
            group.initDeviceInfoList(getDeviceInfoDao().findDeviceInfoListByGroupId(group.id))
        }
        return groupList
*/

        val deviceGroupList = getDeviceGroupDao().deviceGroupListWithInfo()
        val groupList = ArrayList<DeviceGroup>(deviceGroupList.size)
        for (deviceGroupWithInfo in deviceGroupList) {
            if (deviceGroupWithInfo.isInvalid()) continue
            deviceGroupWithInfo.group!!.initDeviceInfoList(deviceGroupWithInfo.deviceInfoList!!)
            groupList.add(deviceGroupWithInfo.group!!)
        }
        return groupList
    }

    //查询所有分组
    fun findDeviceGroupById(groupId: Int): DeviceGroup? {
        val deviceGroupWithInfo = getDeviceGroupDao().findDeviceGroup(groupId)
        if (deviceGroupWithInfo != null && !deviceGroupWithInfo.isInvalid()) {
            return deviceGroupWithInfo.group?.apply {
                initDeviceInfoList(deviceGroupWithInfo.deviceInfoList!!)
            }
        }
        return null
    }

    //更新组
    fun updateGroup(group: DeviceGroup) {
        getDeviceGroupDao().updateGroup(group)
    }

    /* -----------------------    DeviceInfo相关的搜索     --------------------- */

    //查询是否包含此设备
    fun hasDeviceInfo(mac: String, projectId: Int): Boolean = getDeviceInfoDao().hasDeviceInfo(mac, projectId) > 0

    //添加扫描设备列表
    fun addScanDeviceInfoList(infoList: List<DeviceInfo>) = getDeviceInfoDao().addScanDeviceInfoList(infoList)

    //模糊查找列表分页
    fun findDeviceInfoList(keyword: String, projectId: Int, page: Int, count: Int): List<DeviceInfo> =
        getDeviceInfoDao().findDeviceInfoList(keyword, projectId, page, count)

    //查找分页
    fun findDeviceInfoList(projectId: Int, page: Int, count: Int): List<DeviceInfo> =
        getDeviceInfoDao().findDeviceInfoList(projectId, page, count)

    //更新设备
    fun updateDeviceInfo(deviceInfo: DeviceInfo): Int = getDeviceInfoDao().updateDeviceInfo(deviceInfo)

    //更新设备并有关联到绑定组
    fun updateDeviceInfoAndGroup(deviceInfo: DeviceInfo, preGroupId: Int) {
        val group = getDeviceGroupDao().findDeviceGroupById(preGroupId)
        if (group != null && DeviceInfo.hasGroup(group.id)) {
            group.recycleDeviceInfoNumber(deviceInfo.number)
            getDeviceGroupDao().updateGroup(group)
        }
        getDeviceInfoDao().updateDeviceInfo(deviceInfo)
    }

    //删除设备, 需要考虑有绑定组时
    fun deleteDeviceInfo(deviceInfo: DeviceInfo) {
        if (deviceInfo.hasGroup()) {//先解除绑定
            val group = getDeviceGroupDao().findDeviceGroupById(deviceInfo.groupId)
            if (group != null && DeviceInfo.hasGroup(group.id)) {
                group.recycleDeviceInfoNumber(deviceInfo.number)
                getDeviceGroupDao().updateGroup(group)
            }
        }
        getDeviceInfoDao().deleteDeviceInfo(deviceInfo.id)
    }

    //解除绑定设备
    fun unbindDeviceInfo(deviceInfoId: Int, deviceGroup: DeviceGroup) {
        getDeviceInfoDao().unbindDeviceInfo(deviceInfoId)
        getDeviceGroupDao().updateGroup(deviceGroup)
    }

    //模糊查找出未绑定的列表
    fun findUnBindDeviceInfoList(projectId: Int, keyword: String?): List<DeviceInfo> = if (TextUtils.isEmpty(keyword))
        getDeviceInfoDao().findUnBindDeviceInfoList(projectId) else getDeviceInfoDao().findUnBindDeviceInfoList(projectId, keyword!!)

    //绑定设备组
    fun bindDeviceGroup(group: DeviceGroup, deviceInfoId: Int, number: Int) {
        getDeviceGroupDao().updateGroup(group)
        getDeviceInfoDao().bindDeviceGroup(group.id, deviceInfoId, number)
    }
















    //模糊查找列表分页
    fun findDeviceInfoList(keyword: String, page: Int, count: Int): List<DeviceInfo> =
        getDeviceInfoDao().findDeviceInfoList(keyword, page, count)

    //查找分页
    fun findDeviceInfoList(page: Int, count: Int): List<DeviceInfo> = getDeviceInfoDao().findDeviceInfoList(page, count)
}